package com.ssl.jave.util;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ws.schild.jave.Encoder;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.encode.VideoAttributes;
import ws.schild.jave.info.AudioInfo;
import ws.schild.jave.info.MultimediaInfo;
import ws.schild.jave.info.VideoInfo;

import java.io.File;
import java.util.UUID;

/**
 * 描述：视频压缩工具
 *
 * @author shi_senlin
 * @create 2021/03/06 12:38
 */
public class VideoUtils {
    private static Logger logger = LoggerFactory.getLogger(VideoUtils.class);
    // 音频比特率
    private static Integer maxBitRate = 128000;
    // 音频采样率
    private static Integer maxSamplingRate = 44100;
    // 压缩后视频文件大小 360kb
    private static Integer bitRate = 368640;// 1024*360kb = 368640bit
    // 视频帧率 15f/s
    private static Integer maxFrameRate = 15;
    private static Integer maxWidth = 1280;

    private static Encoder encoder;
    private static AudioAttributes audio;
    private static VideoAttributes video;
    private static EncodingAttributes attr;

    static {
        audio = new AudioAttributes();
        video = new VideoAttributes();
        attr = new EncodingAttributes();
        // ---------------- 设置通用值 -------------
        // 设置音频通用编码格式
        audio.setCodec("aac");// libmp3lame，aac
        // 设置音频比特率,单位:b (比特率越高，清晰度/音质越好，当然文件也就越大 128000 = 182kb)
        audio.setBitRate(new Integer(maxBitRate));
        // 设置重新编码的音频流中使用的声道数（1 =单声道，2 = 双声道（立体声））。如果未设置任何声道值，则编码器将选择默认值 0。
        audio.setChannels(2);
        // 设置编码时候的音量值，未设置为0,如果256，则音量值不会改变
        audio.setVolume(256);
        // 设置音频采样率，单位：赫兹 hz，采样率越高声音的还原度越好，文件越大
        audio.setSamplingRate(maxSamplingRate);
        // 设置视频编码格式
        video.setCodec("h264");
        // 设置视频比特率，比特率越高，清晰度/音质越好，当然文件也就越大 800000 = 800kb
        video.setBitRate(bitRate);
        // 视频帧率：15 f / s  帧率越低，效果越差
        // 设置视频帧率（帧率越低，视频会出现断层，越高让人感觉越连续），单位‘HZ’，15fps。
        video.setFrameRate(maxFrameRate);
        //  设置视频压缩后的大小
        // video.setSize(VideoSize.ntsc);
        attr.setOutputFormat("mp4");
        attr.setAudioAttributes(audio);
        attr.setVideoAttributes(video);
    }

    public static String compress(String videoBase64) throws Exception {
        if (StringUtils.isBlank(videoBase64)) {
            logger.warn("source video base64 is empty!");
            return "";
        }
        String path = new StringBuffer(System.getProperty("java.io.tmpdir")).append(File.separator)
                .append(UUID.randomUUID().toString()).toString();
        String sourcePath = path.concat("_source.mp4");
        String targetPath = path.concat("_target.mp4");
        File sourceFile = new File(sourcePath);
        File targetFile = new File(targetPath);
        // 计算开始时间
        long startTime = System.currentTimeMillis();
        try {
            FileUtils.writeByteArrayToFile(sourceFile, Base64.decodeBase64(videoBase64));
            encoder = new Encoder();
            encoder.encode(new MultimediaObject(sourceFile), targetFile, attr);
            long sourceSize = FileUtils.sizeOf(sourceFile);
            long targetSize = FileUtils.sizeOf(targetFile);
            logger.info("video compress befor size si {}kb, after size is {}kb, consume time {} ms", sourceSize / 1024,
                    targetSize / 1024, (System.currentTimeMillis() - startTime) / 1000);
            return Base64.encodeBase64String(FileUtils.readFileToByteArray(targetFile));
        } catch (Exception e) {
            throw e;
        } finally {
            FileUtils.deleteQuietly(sourceFile);
            FileUtils.deleteQuietly(targetFile);
        }
    }

    /**
     * 获取视频信息
     *
     * @param video
     * @throws EncoderException
     */
    private static void videoInfo(File video) throws EncoderException {
        MultimediaObject multimediaObject = new MultimediaObject(video);
        MultimediaInfo info = multimediaObject.getInfo();
        VideoInfo videoInfo = info.getVideo();
        AudioInfo audioInfo = info.getAudio();
        System.out.println("video:" + videoInfo.toString());
        System.out.println("audio:" + audioInfo.toString());
    }

    public static void main(String[] args) throws Exception {
        String sourcePath = "C:\\Users\\49383\\Desktop\\工作\\腾讯实名认证\\demo\\004.MP4";
        String targetPath = "F:\\test\\001-r.MP4";
        videoInfo(new File(sourcePath));
//        String sourceBase64 = Base64.encodeBase64String(FileUtils.readFileToByteArray(new File(sourcePath)));
//        String targetBase64 = compress(sourceBase64);
//        FileUtils.writeByteArrayToFile(new File(targetPath), Base64.decodeBase64(targetBase64));
    }
}